﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Fixx.Connector;
using System.Net;

namespace FixxVS
{
	public partial class ConnectionSettings : UserControl
	{
		public delegate void ConnectionChangedHandler(object sender, ConnectionSettingsChangeArgs ca);
		public event ConnectionChangedHandler Change = delegate{};

		private FixxPersistantStorage _Store { get; set; }
		private bool Initialized { get; set; }

		public ConnectionSettings()
		{
			InitializeComponent();
		}

		private void btnTestConnection_Click(object sender, EventArgs e)
		{
			
			this.lblResult.Visible = false;
			this.lblExplanation.Visible = false;
			int port = 0;
			int timeOut = 60;
			epHost.Clear();
			epPort.Clear();
			epUsername.Clear();
			epPassword.Clear();
			if (string.IsNullOrEmpty(this.txbHost.Text))
				epHost.SetError(this.txbHost, "Host should not be empty");

			else if (string.IsNullOrEmpty(this.txbPort.Text))
				epPort.SetError(this.txbPort, "Port should not be empty");

			else if (!int.TryParse(this.txbTimeOut.Text, out timeOut))
				epTimeOut.SetError(this.txbTimeOut, "TimeOut should be a valid integer.");

			else if (!int.TryParse(this.txbPort.Text, out port))
				epPort.SetError(this.txbPort, "Port should be a valid integer.");

			else if (string.IsNullOrEmpty(this.txbUsername.Text))
				epUsername.SetError(this.txbUsername, "Username should not be empty");

			else if (string.IsNullOrEmpty(this.txbPassword.Text))
				epPassword.SetError(this.txbPassword, "Password should not be empty");

			else
			{
				this.btnTestConnection.Enabled = false;
				this.picLoading.Visible = true;
				var settings = new FixxVSSettings(this.txbUsername.Text, this.txbPassword.Text, this.txbHost.Text, port, timeOut * 1000);
				var repos = new FixxRepository(settings);
				repos.Login((user) =>
					{
						this.SafeInvoke(() =>
							{
								this.lblResult.Visible = true;
								this.lblResult.BackColor = Color.YellowGreen;
								this.lblResult.Image = FixxVS.CommandBar.accept;

								this.lblResult.Text = "Connection Succeeded";
								this.picLoading.Visible = false;
								this.btnTestConnection.Enabled = true;
								this.ThrowChangedEvent(true);
							});
					},
					(error) =>
					{
						this.SafeInvoke(() =>
							{
								this.lblResult.BackColor = Color.Red;
								this.lblResult.Image = FixxVS.CommandBar.error;

								this.lblResult.Visible = true;
								this.lblResult.Text = "Connection Failed";
								//this.lblResult.BackColor
								this.lblExplanation.Visible = true;
								if (error.HttpStatusCode == HttpStatusCode.Unauthorized)
									this.lblExplanation.Text = "Incorrect username and/or password.";
								else if (error.Type == FixxErrorType.Server)
									this.lblExplanation.Text = string.Format("Server returned {0}: {1}", error.HttpStatusCode, error.Message);
								else
									this.lblExplanation.Text = error.Message;

								this.picLoading.Visible = false;
								this.btnTestConnection.Enabled = true;
								this.ThrowChangedEvent(false);
							});
					}
				);


			}



		}

		private void ThrowChangedEvent(bool valid)
		{
			int port = 0;
			int.TryParse(this.txbPort.Text, out port);
			int timeOut = 60;
			int.TryParse(this.txbTimeOut.Text, out timeOut);

			
			bool changed = false;

			if (this._Store != null
				&& this._Store.Repository != null
				&& this._Store.Repository.FixxSettings != null)
			{
				var fs = this._Store.Repository.FixxSettings;
				changed = this.txbHost.Text != fs.Host;
				changed = changed || port != fs.Port;
				changed = changed || timeOut != fs.TimeOut;
				changed = changed || this.txbUsername.Text != fs.Username;
				changed = changed || this.txbPassword.Text != fs.Password;
			}
			else
				changed = true;

			this.Change(this, new ConnectionSettingsChangeArgs()
			{
				Changed = changed,
				Valid = valid,
				TimeOut = timeOut,
				Username = this.txbUsername.Text,
				Password = this.txbPassword.Text,
				Host = this.txbHost.Text,
				Port = port
			});
		}

		private void ConnectionSettings_Load(object sender, EventArgs e)
		{
			var store = new FixxPersistantStorage();
			if (store != null && store.Repository != null && store.Repository.FixxSettings != null)
			{
				var fs = store.Repository.FixxSettings;
				this.txbHost.Text = fs.Host;
				this.txbPort.Text = fs.Port.ToString();
				this.txbUsername.Text = fs.Username;
				this.txbPassword.Text = fs.Password;
				this.txbTimeOut.Text = (fs.TimeOut > 1000)
					? (fs.TimeOut / 1000).ToString()
					: "60";

				this._Store = store;
			}
			else
			{
				this.txbHost.Text = "localhost";
				this.txbPort.Text = "9000";
				this.txbTimeOut.Text = "60";
			}
			this.Initialized = true;
		}

		private void txbUsername_TextChanged(object sender, EventArgs e)
		{
			if (!this.Initialized)
				return;

			this.ThrowChangedEvent(false);
		}
	}
}
